from concurrent.futures import thread
import os
import socket
import threading
import time
import queue
import keyboard

"""
UDP客户端自动测试程序
1、UDP客户端接收任务，接收数据，并将数据保存到接收队列中
2、UDP客户端发送任务，将接收队列中的数据自动发送至UDP服务器，从而进行回环测试
"""

### UDP服务器地址和端口，按实际环境设置
udp_server_host = "192.168.43.230"
udp_server_port = 14550

### UDP当前环境地址和端口，按实际环境测试
udp_current_host = "192.168.43.230"
udp_current_port = 6060

### UDP客户端接收和发送缓冲区，同步队列
socket_rec_queue = queue.Queue(0)
socket_send_queue = queue.Queue(0)

### 是否提示调试信息
SYS_DEBUG_ENABLE = True

def udp_send_task(udp):
    global SYS_DEBUG_ENABLE
    udp.sendall(b'Hello UDP server')
    while True:
        try:
            while (not socket_rec_queue.empty()):
                data = socket_rec_queue.get()[1]
                udp.sendall(data)
                if SYS_DEBUG_ENABLE: print("UDP Client Send Data Len: %d" % (len(data)))
        except:
            print("UDP Client error!")
            socket_rec_queue.queue.clear()
                
        time.sleep(0.005)

def udp_rec_task(udp):
    udp_send_td = threading.Thread(target=udp_send_task, args=(udp,))
    udp_send_td.start()
    print("UDP Client start rec:---")

    while True:
        data = udp.recv(4096)

        socket_rec_queue.put((udp, data))

        if SYS_DEBUG_ENABLE: 
            print("UDP Client Rec: %d" % (len(data)))
            #print("%s" % (str(data, "UTF-8"),), end='')


### 监听按键，退出程序
def app_exit(udp):
    udp.close()
    print("Key: CTRL+X")
    os._exit(0)

if __name__ == '__main__':
    print("<...UDP Client auto test...>\n")
    print("Exit: CTRL+X")

    udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    udp_client.bind((udp_current_host, udp_current_port))
    udp_client.connect((udp_server_host, udp_server_port))

    udp_rec_td = threading.Thread(target=udp_rec_task, args=(udp_client,))
    udp_rec_td.start()

    keyboard.add_hotkey("ctrl+x", app_exit, args=(udp_client,))

